import { _decorator, Component, Node, Prefab, assetManager, instantiate, Tween } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('AutoGenerate')
export class AutoGenerate extends Component {

  @property(Node) monstersNode: Node
  @property(Node) terrainsNode: Node
  @property(Node) playerNode: Node

  fishsMap: Map<string, Prefab> = new Map()
  fishsKeys: string[] = []
  terrainsMap: Map<string, Prefab> = new Map()
  terrainsKeys: string[] = []

  diameter: number = 0 // 直径
  isFishInit: boolean = false // 鱼的预制体是否初始化完毕
  isTerrainInit: boolean = false // 地形的预制体是否初始化完毕
  maxFishCount: number = 10
  fishCount: number = 0
  terrainsNodeTween: Tween<Node> = new Tween()

  start() {
    this.diameter = this.node.children[0].getScale().x * 10
    this.terrainsNode.setPosition(0, -this.diameter / 20, 0)

    // 当 Asset Bundle 被加载过之后，会被缓存下来，此时开发者可以使用 Asset Bundle 名称来获取该 bundle。例如：
    const bundle = assetManager.getBundle('res');
    bundle.loadDir('arts/fishs', Prefab, (err, assets) => {
      // console.log(assets);
      for (let i = 0; i < assets.length; i++) {
        const prefab: Prefab = assets[i];
        this.fishsMap.set(prefab.data.name, prefab)
      }
      this.fishsCallback()
    })
    bundle.loadDir('arts/terrains', Prefab, (err, assets) => {
      // console.log(assets);
      for (let i = 0; i < assets.length; i++) {
        const prefab: Prefab = assets[i];
        this.terrainsMap.set(prefab.data.name, prefab)
      }
      this.terrainsCallback()
    })
  }

  update(deltaTime: number) {
    this.fishUpdate()
  }

  fishsCallback() {
    // console.log('fishsCallback');
    const keys = this.fishsMap.keys()
    for (const key of keys) {
      this.fishsKeys.push(key)
    }
    // console.log(this.fishsKeys);
    this.isFishInit = true
  }

  terrainsCallback() {
    // console.log('terrainsCallback');
    const keys = this.terrainsMap.keys()
    for (const key of keys) {
      this.terrainsKeys.push(key)
    }
    // console.log(this.fishsKeys);

    const diameter = this.diameter // 直径

    // 随机生成100个地形
    for (let i = 0; i < diameter / (diameter / 400); i++) {

      // 随机下标=>随机地形字符串键=>随机地形预制体=>实例化预制体 
      const index = Math.floor(Math.random() * this.terrainsKeys.length)
      // const key = this.terrainsKeys[index]
      const key = 'SeaWeed'
      const str = String(Math.floor(Math.random() * 3))
      const prefab = this.terrainsMap.get(str != '0' ? key + str : key)
      const node = instantiate(prefab)

      // 随机坐标 
      const pos = node.getPosition()
      pos.x = Math.random() * diameter - diameter / 2
      pos.z = Math.random() * diameter - diameter / 2
      pos.y = 0
      node.setPosition(pos)

      // 随机大小
      const scale = node.getScale()
      const val = Math.random() * (diameter / 20) + 1
      scale.set(val, val, val)
      node.setScale(scale)

      // 添加子节点
      this.terrainsNode.addChild(node)
    }

    const pos = this.terrainsNode.getPosition()
    pos.y *= -1
    this.terrainsNodeTween.target(this.terrainsNode).by(1, {
      position: pos,
    }, {
      onComplete: () => {
        this.isTerrainInit = true;
      }
    }).start()

  }

  fishUpdate() {
    this.fishCount = this.monstersNode.children.length

    // 检测是否初始化完毕
    if (!this.isFishInit && !this.isTerrainInit) {
      return
    }

    // 检测数量
    if (this.fishCount >= this.maxFishCount) {
      return
    }

    // 随机鱼
    // 随机下标=>随机鱼字符串键=>随机鱼预制体=>实例化预制体 
    const index = Math.floor(Math.random() * this.fishsKeys.length)
    const key = this.fishsKeys[index]
    // const key = 'Hammerhead'
    const prefab = this.fishsMap.get(key)
    const node = instantiate(prefab)

    // 随机大小
    // 根据角色的大小上下浮动10 差值20
    const playerScale = this.playerNode.getScale().x
    let scale = Math.random() * 5 - 2.5 + playerScale
    scale = scale < 0 ? 0.8 : scale
    scale /= (node.children[0].getScale().x / this.playerNode.children[0].children[0].getScale().x)
    node.setScale(scale, scale, scale)

    // 随机起点坐标
    // (x)2 + (y)2 + (z)2 = (r)2
    const radius = this.diameter / 2 + scale
    const x = (Math.random() * radius * 2) - radius
    const z = (Math.random() * radius * 2) - radius
    const y = Math.sqrt(Math.pow(radius, 2) - Math.pow(x, 2) - Math.pow(z, 2))
    const pos = node.getPosition()
    pos.x = x
    pos.z = z
    pos.y = y
    node.setPosition(pos)

    // 添加子节点
    this.monstersNode.addChild(node)
    this.fishCount++
  }

}


